package com.example.app.utils;

import com.example.app.constants.CommonConstants;
import com.example.app.dao.mongdb.MongoUserRepository;
import com.example.app.model.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.ResponseBody;

import java.security.PublicKey;

/**
 * Created by wangtao on 2018/3/2.
 */
@Configuration
@ResponseBody
public class JwtHelper {
    private Logger logger = LoggerFactory.getLogger(JwtHelper.class);
    @Value("${jwt.user.pubKey.path}")
    private String userPubKeyPath;
    @Autowired
    private MongoUserRepository mongoUserRepository;

    /**
     * 解析token
     *
     * @param token
     * @return
     * @throws Exception
     */
    public Jws<Claims> parserToken(String token, String pubKeyPath) throws Exception {
        PublicKey publicKey = KeyHelper.getPublicKey(pubKeyPath);
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
        return claimsJws;
    }

    /**
     * 从token中解析用户信息
     *
     * @param token
     * @return
     */
    public User getUserByToken(String token) throws Exception {
        User user = null;
        try {
            Jws<Claims> claimsJws = parserToken(token, userPubKeyPath);
            Claims body = claimsJws.getBody();
            user = mongoUserRepository.findOne(body.get(CommonConstants.JWT_KEY_USER_ID, Long.class));
        } catch (IllegalArgumentException e) {
            throw new Exception("access_token不能为空!");
        } catch (ExpiredJwtException e) {
            throw e;
        } catch (Exception e) {
            logger.error("Token parse failed!", e);
            throw new Exception("access_token无效!");
        }
        return user;
    }
}
